package cn.ac.sec.oil.netty;

import org.apache.log4j.Logger;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class NettyServer {
	
	private static final Logger LOG = Logger.getLogger(NettyServer.class);
	private int port;

	public NettyServer(int port) {
		this.port = port;
	}

	public void run() throws Exception {
		
		EventLoopGroup bossGroup = new NioEventLoopGroup(); //(1)Netty内部通过线程处理各种数据，EventLoopGroup是用来管理调度他们的，注册Channel，管理他们生命周期
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			
			ServerBootstrap b = new ServerBootstrap(); //(2)ServerBootstrap负责初始化netty服务器，并且开始监听端口的socket请求
			b.group(bossGroup, workerGroup) //(3)
					.channel(NioServerSocketChannel.class)
					.childHandler(new NettyServerInitializer())
					.option(ChannelOption.SO_BACKLOG, 128)
//					.handler(new NettyServerHandler());// (5)
					.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)

			ChannelFuture f = b.bind(port).sync(); // (7)Bind and start to accept incoming connections

			// Wait until the server socket is closed.
			// In this example, this does not happen, but you can do that to gracefully shut down your server.
			f.channel().closeFuture().sync();
		} finally {
			workerGroup.shutdownGracefully();
			bossGroup.shutdownGracefully();
		}
	}

	public static void main(String[] args) throws Exception {
		
		int port;
		if (args.length > 0) {
			port = Integer.parseInt(args[0]);
		} else {
			port = 12345;
		}
		LOG.info("server started on port: " + port);
		new NettyServer(port).run();
	}

}
